package org.dandsoft.blackbox.snn;

import org.dandsoft.blackbox.snn.study.StudyPhase;
import org.dandsoft.blackbox.snn.study.StudyStatus;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: dvilyuzhanin
 * Date: 16.03.2009 18:49:55
 */
public class Trigger {

    public enum State {
        New, Teen, Adult, Old, Output
    }

    private ObjectId id;
    private List<Synapse> synapses = new LinkedList<Synapse>();
    private Value bar = Value.PASSIVE;
    private State state = State.New;
    private Value value;
    private StudyStatus studyStatus = new StudyStatus();
    private int lazyTime;

    /**
     * @param environment
     */
    public void activate(Environment environment) {
        this.value = Value.PASSIVE;
        Value state = Value.PASSIVE;
        Value maxValue = Value.PASSIVE;
        //перебираем все синапсы
        for (Synapse synapse : synapses) {
            maxValue = maxValue.add(synapse.getWeight());
            Value value = environment.get(synapse.getSignalId());
            if (value != null) {
                //синапс имеет актиность
                synapse.setValue(value);
                if (synapse.getMinValue().isLowerEquals(value) && synapse.getMaxValue().isGreaterEquals(value)) {
                    //сигнал узнан
                    state = state.add(synapse.getWeight());
                    synapse.setUseful(true);
                    //оповещаем о полезности сигнала
                    environment.notifyUsefulUsing(this.id, synapse.getSignalId());

                } else {
                    //синапс оказался бесполезный и на его входе не узнанный им сигнал.
                    synapse.setUseful(false);
                }
            } else {
                synapse.setValue(null);
            }
        }
        Value result = state.countOutValue(maxValue, bar);
        if (result.isLower(Value.PASSIVE)) {
            result = Value.PASSIVE;
        }
        //передаем свою реакцию в окружение
        environment.put(id, result);
        this.value = result;

    }


    /**
     * <p>
     * <p/>
     * </p>                                          \
     * <p/>
     * <p>
     * w1 1 - 0.333     2 - 0.5     3 - 0.6     3 - 0.5
     * w2 1 - 0.333     1 - 0.25    1 - 0.2     2 - 0.333
     * w3 1 - 0.333     1 - 0.25    1 - 0.2     1 - 0.2
     * y  3 - 1         4 - 1       5 - 1       6 - 1
     * </p>
     */

    protected void studyUseless() {
        if (this.value.isGreater(Value.PASSIVE)) {
            for (Synapse synapse : synapses) {
                if (this.value.isGreater(Value.PASSIVE)) {
                    //������� �������
                    if (!synapse.isUseful() && synapse.getValue() != null) {
                        //(FY-������)����������� ������ ����������
                        try {
                            synapse.correct();
                        } catch (NullPointerException e) {
                            e.printStackTrace();
                        }
                    } else {
                        //��� ������� ��� ���������
                        synapse.setWeight(synapse.getWeight().increment());
                        this.bar = this.bar.increment();
                    }
                } else {
                    //������� �� �������, �� ���� ������ �� ������.
                    //�������� ��� ������ ����������
                }
            }
        }
    }


    public void connect(ObjectId id, Value value) {
        Synapse synapse = new Synapse();
        synapse.setSignalId(id);
        synapse.setMinValue(value);
        synapse.setMaxValue(value);
        synapse.setWeight(Value.ACTIVE);
        this.bar = bar.add(Value.ACTIVE);
        synapses.add(synapse);
    }

    public List<Synapse> getSynapses() {
        return synapses;
    }

    public void setSynapses(List<Synapse> synapses) {
        this.synapses = synapses;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public StudyStatus getStudyStatus() {
        return studyStatus;
    }


}
